package com.kkks.spring_rest.tick.dao.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
//import org.springframework.transaction.annotation.Propagation;
//import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.kkks.spring_rest.tick.dao.JdbcBaseDao;

/**
 * @author SC
 * @version 1.0
 * @created 2012-6-19 下午04:58:43
 * @describe
 */

@Repository("jdbcBaseDao")
//@Transactional
public class JdbcBaseDaoImpl<T> implements JdbcBaseDao<T> {

	private static final Logger logger = Logger
			.getLogger(JdbcBaseDaoImpl.class);
	@Autowired
	private JdbcTemplate jdbcTemplate;

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public JdbcBaseDaoImpl() {
	}

	/**
	 * 描述 执行一条 sql 语句
	 * 
	 * @param sql
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=false, rollbackFor=Exception.class)
	public void execute(String sql) {// TODO
		Assert.hasText(sql, "sql must be not null !");
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			this.getJdbcTemplate().execute(sql);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：" + sql, e);
			throw e;
		}
	}

	/**
	 * 描述 执行一组sql语句
	 * 
	 * @param sql
	 *            update ca_user set a ='new' ,b=3 where c = 5
	 * @return an array containing the numbers of rows affected by each update
	 *         in the batch
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=false, rollbackFor=Exception.class)
	public int[] batchUpdate(String[] sql) {// TODO
		try {
			if (logger.isDebugEnabled()) {
				for (String values : sql) {
					logger.debug("开始执行sql 语句" + values);
				}
			}
			return this.getJdbcTemplate().batchUpdate(sql);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
	}

	/**
	 * 描述 执行一组sql语句 注意：这里的sql不支持 命名参数，只能用 ? 代替 update ca_user set a =? ,b=?
	 * where c = ?
	 * 
	 * @param sql
	 * @param object
	 * @return an array containing the numbers of rows affected by each update
	 *         in the batch
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=false, rollbackFor=Exception.class)
	public int[] batchUpdate(String sql, final List<Object[]> object) {// TODO
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句");
			}
			return this.getJdbcTemplate().batchUpdate(sql, object);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
	}

	/**
	 * 描述 更新sql语句的执行，没有参数的情况
	 * 
	 * @param sql (such as insert update or delete statement)
	 * @return an array containing the numbers of rows affected by each update
	 *         in the batch
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=false, rollbackFor=Exception.class)
	public boolean update(String sql) {// TODO
		Assert.hasText(sql, "sql must be not null");
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句");
			}
			return this.getJdbcTemplate().update(sql) > 0;
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
	}

	/**
	 * 描述 多个参数的更新语句
	 * 
	 * @param sql
	 * @param objects
	 * @return 受影响的行数 boolean
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=false, rollbackFor=Exception.class)
	public boolean update(String sql, Object...objects) {// TODO
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			return this.getJdbcTemplate().update(sql, objects) > 0;
					
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
	}




	/**
	 * 描述 查询单列(类型为整型)，返回一个指定类型的值
	 * 
	 * @param sql
	 *            select count(*) from demo where a =: a and b =: b select nid
	 *            from demo where a =: a and b =: b ;
	 * @param paramMap
	 * @return the result object of the required type, or null in case of SQL
	 *         NULL
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public Object queryForObject(String sql, Class<T> requiredType, Object...objects) {// TODO
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			return this.getJdbcTemplate().queryForObject(sql, requiredType, objects);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
	}

	
	/**
	 * 描述 泛型查询列表
	 * 
	 * @param <T>
	 * @param sql
	 *            elementType - the required type of element in the result list
	 *            (for example, Integer.class)
	 * @param elementType
	 * @return a List of objects that match the specified element type 即为基本的数据类型
	 */
	@SuppressWarnings("hiding")
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public <T> List<T> queryForObjectList(String sql, Class<T> elementType) {// TODO
		List<T> list = new ArrayList<T>();
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			list = this.getJdbcTemplate().queryForList(sql, elementType);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
		return list;
	}
	/**
	 * 泛型查询列表，分页接口
	 * @param sql
	 * @param currentPage
	 * @param elementType
	 * @param rowNum
	 * @return List<T>
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public  Page queryForObjectPaginationList(String sql, Class<T> elementType, int currentPage, int rowNum ){
		Page page = new Page();// TODO
		if(sql != null){
			
			try {
				String countSQL = page.getSQLCount(sql);  
				page.setPageNum(currentPage);  
				page.setTotalCount(rowNum, this.jdbcTemplate.queryForInt(countSQL));  
		        int startIndex = (currentPage - 1) * rowNum;    //数据读取起始index
		        
		        StringBuffer paginationSQL = new StringBuffer(" ");  
		        paginationSQL.append(sql);  
		        paginationSQL.append(" limit "+ startIndex+","+rowNum);
		        page.setResult(this.jdbcTemplate.queryForList(paginationSQL.toString(), elementType));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return page;
	}
	/**
	 * 描述 带参数的泛型查询
	 * 
	 * @param <T>
	 * @param sql
	 * @param elementType
	 *            - the required type of element in the result list (for
	 *            example, Integer.class)
	 * @param args
	 * @return a List of objects that match the specified element type
	 */
	@SuppressWarnings({ "hiding" })
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public <T> List<T> queryForObjectList(String sql, int[] argTypes, Class<T> elementType, Object... args) {// TODO
		List<T> list = new ArrayList<T>();
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			list = (List<T>) this.getJdbcTemplate().queryForList(sql, args, argTypes, elementType);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
		return list;
	}
	/**
	 * 描述 带参数的泛型查询 分页接口
	 * @param sql
	 * @param elementType
	 * @param currentPage
	 * @param rowNum
	 * @param args
	 * @return Page<T>
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public  Page queryForObjectPaginationList(String sql, int[] argTypes, Class<T> elementType, int currentPage, int rowNum, Object... args ){
		// TODO
		Page page = new Page();
		if(sql != null){
			try {
				String countSQL = page.getSQLCount(sql);  
				page.setPageNum(currentPage);  
				page.setTotalCount(rowNum, this.jdbcTemplate.queryForInt(countSQL, args, argTypes));
		        int startIndex = (currentPage - 1) * rowNum;    //数据读取起始index
		        
		        StringBuffer paginationSQL = new StringBuffer(" ");  
		        paginationSQL.append(sql);  
		        paginationSQL.append(" limit "+ startIndex+","+rowNum);
		        page.setResult(this.jdbcTemplate.queryForList(paginationSQL.toString(), elementType, args));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return page;
	}
	/**
	 * 描述 查询实体对象，泛型
	 * 
	 * @param <T>
	 * @param sql
	 * @param rowMapper
	 * @param args
	 * @return T
	 */
	@SuppressWarnings({ "hiding" })
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public <T> T queryForEntity(String sql, RowMapper<T> rowMapper, Object... args) {// TODO
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			return (T) this.getJdbcTemplate().queryForObject(sql,rowMapper, args);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
	}
	

	/**
	 * 描述 查询一条sql，返回列表
	 * 
	 * @param sql
	 * @return <Map<String,Object>>an List that contains a Map per row
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public List<Map<String, Object>> queryForEntityList(String sql) {// TODO
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			list = this.getJdbcTemplate().queryForList(sql);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
		return list;
	}
	/**
	 * 描述 查询一条sql，返回列表分页接口
	 * @param sql
	 * @param currentPage
	 * @param rowNum
	 * @return
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public Page  queryForEntityPaginationList(String sql, int currentPage, int rowNum){// TODO
		
		Page page = new Page();
		try {
			String countSQL = page.getSQLCount(sql);  
			page.setPageNum(currentPage);  
			page.setTotalCount(rowNum, this.jdbcTemplate.queryForInt(countSQL));  
	        int startIndex = (currentPage - 1) * rowNum;    //数据读取起始index
	        
	        StringBuffer paginationSQL = new StringBuffer(" ");  
	        paginationSQL.append(sql);  
	        paginationSQL.append(" limit "+ startIndex+","+rowNum);
	        page.setList(this.jdbcTemplate.queryForList(paginationSQL.toString()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return page;
	}
	
	/**
	 * 描述 带参数的列表查询
	 * 
	 * @param sql
	 * @param args
	 * @return a List that contains a Map per row
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public List<Map<String, Object>> queryForEntityList(String sql, Object... args) {// TODO
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("开始执行sql 语句" + sql);
			}
			list = this.getJdbcTemplate().queryForList(sql, args);
		} catch (RuntimeException e) {
			logger.error("执行sql 语句异常：", e);
			throw e;
		}
		return list;
	}
	/**
	 * 描述 带参数的列表查询 分页接口
	 * @param sql
	 * @param currentPage
	 * @param rowNum
	 * @param args
	 * @return Page
	 */
//	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public Page queryForEntityPaginationList(String sql, int currentPage, int rowNum, Object... args) {// TODO
		Page page = new Page();
		try {
			String countSQL = page.getSQLCount(sql);  
			page.setPageNum(currentPage);  
			page.setTotalCount(rowNum, this.jdbcTemplate.queryForInt(countSQL, args));  
	        int startIndex = (currentPage - 1) * rowNum;    //数据读取起始index
	        
	        StringBuffer paginationSQL = new StringBuffer(" ");  
	        paginationSQL.append(sql);  
	        paginationSQL.append(" limit "+ startIndex+","+rowNum);
	        page.setList(this.jdbcTemplate.queryForList(paginationSQL.toString(), args));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return page;
	}

}
